package com.hn658.groupshare.account.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hn658.framework.dataaccess.pagination.GenericPage;
import com.hn658.framework.shared.utils.UUIDUtils;
import com.hn658.groupshare.account.dao.db.IUserAccountDbDao;
import com.hn658.groupshare.account.dao.redis.IUserAccountRedisDao;
import com.hn658.groupshare.account.entity.UserAccountEO;
import com.hn658.groupshare.account.exception.UserAccountException;
import com.hn658.groupshare.account.service.IUserAccountService;

/**
 * 用户账户服务类
 * @author ztjie
 *
 */
@Service
public class UserAccountServiceImpl implements IUserAccountService {

	@Autowired
	private IUserAccountDbDao accountDbDao;
	@Autowired
	private IUserAccountRedisDao userAccountRedisDao;

	@Override
	public UserAccountEO findUserByUid(Long userId) {
		if (userId == null) {
			return null;
		}
		// 从redis中查询用户信息
		UserAccountEO userInfo = userAccountRedisDao.getUserById(userId);
		// redis中无信息，从db数据库中查询
		if (userInfo == null) {
			userInfo = accountDbDao.selectUniqueByProp("id", userId);
			// 如过在DB中找到对应信息返回，并将信息存入Redis中
			if (userInfo != null) {
				userAccountRedisDao.saveUserInfo(userInfo,null);
			}
		}
		return userInfo;
	}

	public UserAccountEO findUserByMobilePhone(String mobilePhone) {
		// 从redis中查询用户信息
		UserAccountEO userInfo = userAccountRedisDao.getUserByMobilePhone(mobilePhone);
		
		if (userInfo!=null) {
			if (!mobilePhone.equals(userInfo.getMobilePhone())) {
				userInfo = null;
			}
		}
		
		if (userInfo == null) {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("mobilePhone", mobilePhone);
			param.put("isDeleted", false);
			List<UserAccountEO> list = accountDbDao.selectByMap(param);
			/**
			 *手机号相同的记录存在多条，但是同时有效的不能有多条
			 */
			if (list!=null && list.size()>=1) {
				userInfo = list.get(0);
			}
			// 如过在DB中找到对应信息返回，并将信息存入Redis中
			if (userInfo != null) {
				userAccountRedisDao.saveUserInfo(userInfo,null);
			}
		}
		return userInfo;
	}

	@Override
	public void update(UserAccountEO userInfo) {
		accountDbDao.update(userInfo);
		userAccountRedisDao.delete(userInfo.getId());
	}
	
	@Override
	public GenericPage<UserAccountEO> query(Map<String, Object> queryParam,
			int pageSize, int startIndex, String orderBy, boolean isAsc) {
		if(queryParam==null){
			queryParam = new HashMap<String, Object>();
		}
		queryParam.put("isDeleted", false);
		return accountDbDao.selectByMap(queryParam, pageSize, startIndex, orderBy, isAsc);
	}
	
	public void removeUser(Long id) {
		if (id == null) {
			throw new UserAccountException(UserAccountException.AccountIdIsBlank);
		}
		UserAccountEO dbUser = accountDbDao.selectUniqueByProp("id", id);
		if (dbUser == null) {
			throw new UserAccountException(UserAccountException.AccountNotExitedWrong);
		}
		dbUser.setIsDeleted(true);
		accountDbDao.update(dbUser);
		// 更新redis
		userAccountRedisDao.delete(id);
	}

	@Override
	@Transactional
	public UserAccountEO register(UserAccountEO userInfo) {
        // 校验账号是否存在
    	UserAccountEO dbUser = findUserByUid(userInfo.getId());
        if (dbUser != null) {
            throw new UserAccountException(UserAccountException.AccountIsExist);
        }
		userInfo.setCreateTime(new Date());
		userInfo.setLastUpdateTime(new Date());
		userInfo.setIsDeleted(false);
		accountDbDao.insert(userInfo); // 保存基本信息
		userAccountRedisDao.saveUserInfo(userInfo,null); // 保存redis
		return userInfo;
	}

	@Override
	public UserAccountEO getUserByAuthkey(String authkey) {
		Long uid = userAccountRedisDao.getUidByAuthkey(authkey);
		if(uid==null){
			return null;
		}
		return this.findUserByUid(uid);
	}

	@Override
	public String createSession(Long uid) {
		// 生成新的authkey
		String authkey = UUIDUtils.getUUID();
		// 保存authkey
		userAccountRedisDao.setUserAuthkey(uid, authkey);
		return authkey;
	}
	
	@Override
	public void removeSession(Long uid) {
		userAccountRedisDao.removeUserAuthkey(uid);
	}

}
